home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr48
/
386p_200.zip
/
386JOY.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-01-14
|
13KB
|
541 lines
; Joystick control module
; <bashing mode on>
; Grrr! Why those wimpy IBM engineers chosed a stupid analog interface ?!?!?
; Heck! If at least they included enough hardware support this
; could have been a little problem, but ...argh!...
; I hate polling things when lots of IRQs keeps knocking on the P.I.C. !!!!
; Of course this is the "default stick" handling code, if you plan to
; add cooler sticks, just write a XID driver and let it take control.
; <bashing mode off>
;
; Well, this is my "safe" joystick handling code
; there are better ways to handle sticks, but i know this works on anything
; _InitStick
; _ReadStick
.386P
code32 segment para public use32
assume cs:code32,ds:code32
include 386power.inc
include 386video.inc
include pix.inc
include chario.inc
include 386keyb.inc
include 386menu.inc
; What is needed to read the joystick port:
;1. Trigger the joystick oneshots with an 'out' to 0x201.
; This will set all of the joystick bits on.
;2. Read (in) 0x201, finding:
; Bit Contents
; 0 Joystick A X coordinate
; 1 Joystick A Y coordinate
; 2 Joystick B X coordinate
; 3 Joystick B Y coordinate
; 4 Button A 1
; 5 Button A 2
; 6 Button B 1
; 7 Button B 2
;
;3. Continue reading 0x201 until ALL oneshots return to zero
; (i've seen lots of joystic routines that seems to miss this)
; recording the loop during which each bit falls to zero.
; The duration of the pulse from each oneshot may be used to
; determine the resistive load (from 0 to 100K) from each
; Joystick, as: Time = 24.2msec. + .011 (r) msec.
;
;4. To do this correctly, I recommend calibrating the joystick;
; have the user move the stick to each corner, then center it,
; while recording the resulting values.
align dword
; the following DWORDS the "downcount value" reached when
; the corresponding bit in the joystick port
; has gone under the "logic 1" threshold value.
_JX_A dd 0
_JY_A dd 0
_JX_B dd 0
_JY_B dd 0
_B1_A dd 0
_B2_A dd 0
_B1_B dd 0
_B2_B dd 0
; calibration parameters for joystick A
A_YUP dd 0
A_XLEFT dd 0
A_YCENTER dd 0
A_XCENTER dd 0
A_YDOWN dd 0
A_XRIGHT dd 0
; calibration parameters for joystick B
B_YUP dd 0
B_XLEFT dd 0
B_YCENTER dd 0
B_XCENTER dd 0
B_YDOWN dd 0
B_XRIGHT dd 0
_BUTTON dd 0
_POLL_TIME dd 00000FFFFh ; usually this is fast enough
; MAX. NUMBER OF LOOPS WE HAVE TO PERFORM
; TO COMPLETELY DECODE THE JOYSTICK PORT
; (during calibration it will be set to the higher
; "poll" value to speed up joystick reads)
JPORT equ 0201h
; MAX. 30 chars for every name
IBMStick db 'plain joystick',0
; joysticks name table
public _StickName
_StickName dd offset IBMStick
dd 0,0,0
; check joystick
SOK dd offset OkMIStick,offset snone,offset snone,offset snone
; init stick table
IStick dd offset MIStick, offset snone, offset snone, offset snone
align byte
public _StickOK
_StickOK:
jmp [esi*4+SOK]
OkMIStick:
stc
ret
public _InitStick
_InitStick:
jmp [esi*4+IStick]
nojoys db 'XID: Invalid joystick device',CR,LF,'$'
snone: mov _386Return,offset nojoys
jmp _Exit
head db ' pc joystick calibration ',0
tail db ' and press a button ',0
center db 'MOVE TO CENTRAL POSITION',0
upleft db 'MOVE TO UPPER LEFT POSITION',0
dnright db 'MOVE TO LOWER RIGHT POSITION',0
xug db ' x_1=',0
db ' y_1=',0
db ' x_2=',0
db ' y_2=',0
db 'b0_1=',0
db 'b1_1=',0
db 'b0_2=',0
db 'b1_2=',0
ctr1 dd 0
ctr2 dd 0
Shuu:
pushad
mov edi,_ScrBase
mov eax,_VDispX
mov esi,offset _JX_A
mov ctr1,2
add eax,6*8
luup1:
mov edx,_VDispY
add edx,100
mov ctr2,4
luup2:
mov ebx,[esi]
add esi,4
mov ecx,8
call _PutUnsigned
mov ecx,16
mov ebx,8
sub eax,_VDispX
sub edx,_VDispY
call _TouchBlock
add eax,_VDispX
add edx,_VDispY
add edx,16
dec ctr2
jnz luup2
add eax,8*(6+8+2+6)
dec ctr1
jnz luup1
call _PageFlip1
popad
ret
Shoo:
; esi = new message
pushad
mov eax,0
call _ScrClr
mov eax,_VDispX
mov edx,_VDispY
add eax,64
add edx,16
mov edi,_ScrBase
mov ebx,offset head
call _PutString
add edx,16
mov ebx,esi
call _PutString
add edx,16
mov ebx,offset tail
call _PutString
; now write the x/y button markers
mov edi,_ScrBase
mov eax,_VDispX
mov ctr1,2
mov ebx,offset xug
bluup1:
mov edx,_VDispY
add edx,100
mov ctr2,4
bluup2:
call _PutString
add ebx,6
add edx,16
dec ctr2
jnz bluup2
add eax,(6+8+2)*8
dec ctr1
jnz bluup1
call _PageFlip0
popad
ret
CP macro a,b
mov eax,b
mov a,eax
endm
ReleaseButton: ;wait until the pressed button is released
call RawStick
mov eax,_BUTTON
cmp _B1_A,eax
jbe ReleaseButton
cmp _B2_A,eax
jbe ReleaseButton
cmp _B1_B,eax
jbe ReleaseButton
cmp _B2_B,eax
jbe ReleaseButton
ret
MIStick: ; main joystick initialization
pushad
; check lower right corner first
; to get maximum poll times
mov esi,offset dnright
call Shoo
rednright:
call RawStick
call Shuu
CP A_XRIGHT,_JX_A
mov ebx,eax
CP A_YDOWN,_JY_A
cmp ebx,eax
ja alto1
mov ebx,eax
alto1:
CP B_XRIGHT,_JX_B
cmp ebx,eax
ja alto2
mov ebx,eax
alto2:
CP B_YDOWN,_JY_B
cmp ebx,eax
ja alto3
mov ebx,eax
alto3: lea eax,[ebx*2]
cmp _B1_A,eax
jbe doned
cmp _B2_A,eax
jbe doned
cmp _B1_B,eax
jbe doned
cmp _B2_B,eax
jnbe rednright
doned: add ebx,4
mov _POLL_TIME,ebx ; set maximum polling time to speed up things
; check upper left corner to get a better button threshold
mov esi,offset upleft
call Shoo
call ReleaseButton
reupleft:
call RawStick
call Shuu
CP A_XLEFT,_JX_A
mov ebx,eax
CP A_YUP,_JY_A
cmp ebx,eax
jb basso1
mov ebx,eax
basso1:
CP B_XLEFT,_JX_B
cmp ebx,eax
jb basso2
mov ebx,eax
basso2:
CP B_YUP,_JY_B
cmp ebx,eax
jb basso3
mov ebx,eax
basso3: shl ebx,1 ; keep a good margin
add ebx,4 ; & set new minimum button threshold
mov _BUTTON,ebx
cmp _B1_A,ebx
jbe doneu
cmp _B2_A,ebx
jbe doneu
cmp _B1_B,ebx
jbe doneu
cmp _B2_B,ebx
jnbe reupleft
doneu:
; check central positions to centrate the x-y thresholds
mov esi,offset center
call Shoo
call ReleaseButton
recenter:
call RawStick
call Shuu
CP A_XCENTER,_JX_A
CP A_YCENTER,_JY_A
CP B_XCENTER,_JX_B
CP B_YCENTER,_JY_B
mov ebx,_BUTTON
cmp _B1_A,ebx
jbe donec
cmp _B2_A,ebx
jbe donec
cmp _B1_B,ebx
jbe donec
cmp _B2_B,ebx
jnbe recenter
donec:
; NOW CALIBRATE THINGS
mov eax,A_XCENTER
add eax,A_XLEFT
shr eax,1
mov A_XLEFT,eax
mov eax,B_XCENTER
add eax,B_XLEFT
shr eax,1
mov B_XLEFT,eax
mov eax,A_YCENTER
add eax,A_YUP
shr eax,1
mov A_YUP,eax
mov eax,B_YCENTER
add eax,B_YUP
shr eax,1
mov B_YUP,eax
; now set the "down right" limits
mov eax,A_XRIGHT
add eax,A_XCENTER
shr eax,1
mov A_XRIGHT,eax
mov eax,B_XRIGHT
add eax,B_XCENTER
shr eax,1
mov B_XRIGHT,eax
mov eax,A_YDOWN
add eax,A_YCENTER
shr eax,1
mov A_YDOWN,eax
mov eax,B_YDOWN
add eax,B_YCENTER
shr eax,1
mov B_YDOWN,eax
mov eax,0
call _ScrClr
call _PageFlip0
popad
ret
RawStick:
mov ecx,_POLL_TIME
mov dx,JPORT
; azzera
xor ebx,ebx
mov _JX_A,ebx
mov _JY_A,ebx
mov _JX_B,ebx
mov _JY_B,ebx
mov _B1_A,ebx
mov _B2_A,ebx
mov _B1_B,ebx
mov _B2_B,ebx
mov al,0FFh ; call me paranoid :)
cli
out dx,al ; trigger RCs
girastick:
in al,dx ; leggi lo stato delle linee del joystick
; aggiorna i contatori
shr al,1
adc _JX_A,ebx
shr al,1
adc _JY_A,ebx
shr al,1
adc _JX_B,ebx
shr al,1
adc _JY_B,ebx
shr al,1
adc _B1_A,ebx
shr al,1
adc _B2_A,ebx
shr al,1
adc _B1_B,ebx
shr al,1
adc _B2_B,ebx
dec ecx
jne girastick
stickdone:
sti
ret
; read stick table
RStick dd offset MRStick,offset snone,offset snone,offset snone
public _ReadStick
_ReadStick:
jmp [esi*4+RStick]
; IN: ESI = STICK DEVICE GROUP
; OUT: EAX = STICK BITS for joystick 0,1
; EDX = STICK BITS for joystick 2,3
;
; AX = STICK0
; EAX high word = STICK1
; DX = STICK2
; EDX high word = STICK3
; Every joystick is described by 16 bits
; (it includes 3D motion and 3D rotation plus four buttons)
; bit meaning
; 0 UP
; 1 DOWN
; 2 LEFT
; 3 RIGHT
; 4 FORWARD
; 5 BACKWARD
; 6 TURN_UP = rotate forward-->up
; 7 TURN_DOWN = rotate forward-->down
; 8 TURN_LEFT = rotate forward-->left
; 9 TURN_RIGHT = rotate forward-->right
; 10 ROLL_LEFT = rotate up-->left
; 11 ROLL_RIGHT = rotate up-->right
; 12 BUTTON_0
; 13 BUTTON_1
; 14 BUTTON_2
; 15 BUTTON_3
J_UP =1
J_DOWN =2
J_LEFT =4
J_RIGHT =8
J_FORWARD =16
J_BACKWARD =32
J_TUP =64
J_TDOWN =128
J_TLEFT =256
J_TRIGHT =512
J_RLEFT =1024
J_RRIGHT =2048
J_B0 =4096
J_B1 =8192
J_B2 =16384
J_B3 =32768
UPPER_STICK =65536
MRStick : ; read main joysticks
push ebx
push ecx
call RawStick
; x axis translation raw->logical
mov ebx,_JX_A
mov eax,J_UP+J_LEFT+((J_LEFT+J_UP)*UPPER_STICK)
cmp ebx,A_XLEFT
jb done_xa
xor al,J_LEFT
cmp ebx,A_XRIGHT
jb done_xa
or al,J_RIGHT
done_xa:
; y axis translation raw->logical
mov ebx,_JY_A
cmp ebx,A_YUP
jb done_ya
xor al,J_UP
cmp ebx,A_YDOWN
jb done_ya
or al,J_DOWN
done_ya:
; traduzione pulsanti 1= pressed 0 = not pressed
mov edx,_BUTTON
cmp _B1_A,edx
ja nob1a
or ax,J_B0
nob1a:
cmp _B2_A,edx
ja nob2a
or ax,J_B1
nob2a: ; NOW TEST SECOND JOYSTICK
mov ebx,_JX_B
cmp ebx,B_XLEFT
jb done_xb
xor eax,UPPER_STICK*J_LEFT
cmp ebx,B_XRIGHT
jb done_xb
or eax,UPPER_STICK*J_RIGHT
done_xb:
; y axis translation raw->logical
mov ebx,_JY_B
cmp ebx,B_YUP
jb done_yb
xor eax,UPPER_STICK*J_UP
cmp ebx,B_YDOWN
jb done_yb
or eax,UPPER_STICK*J_DOWN
done_yb:
; traduzione pulsanti 1= pressed 0 = not pressed
mov edx,_BUTTON
cmp _B1_B,edx
ja nob1b
or eax,UPPER_STICK*J_B0
nob1b:
cmp _B2_B,edx
ja nob2b
or eax,UPPER_STICK*J_B1
nob2b:
; sticks 0,1 present
pop ecx
xor edx,edx ; sticks 2,3 are not present
pop ebx
ret
code32 ends
END